package com.gitee.wsl.coroutines.strategy.fallback

import com.gitee.wsl.base.Option
import com.gitee.wsl.base.empty

import com.gitee.wsl.coroutines.strategy.hot.Policy
import com.gitee.wsl.data.cache.Cache
import com.gitee.wsl.data.cache.memory

import kotlinx.atomicfu.AtomicInt
import kotlinx.atomicfu.atomic


fun <T:Any> fallCall(policy: Policy<T> = FallBack(30), block:()->T):T{
    return policy(block)
}

class FallBack<T:Any>(val value:Int): Policy<T> {
    override fun invoke(block: () -> T): T {
        val saveObject = cache.getOrPut(block){ atomic(0) to Option.empty<T>() }
        val qps = saveObject.first.incrementAndGet()
         if(value > qps)
           throw RuntimeException("to much call")
        return block()
    }

    companion object{
        val cache = Cache.memory<Any,Pair<AtomicInt, Option<Any>>>{
            this.setValidTime(500)
        }
    }
}